#include "visbasewidget.h"

#include "../sagevis.h"
#include "visbasecontainer.h"
#include "visbaseelement.h"
#include "visbaselayout.h"
#include "../VisUtilityClasses/layoutthread.h"
#include"../SageVisGuiElements/lineconnectorelement.h"

VisBaseWidget::VisBaseWidget( QPointer<SageVis> svp, QGraphicsItem *parent) :
    QGraphicsWidget(parent)
{
    sageVisPointer = svp;

    //----- HANDLE LAYOUT THREAD ----
    //  All vis widgets have a layout thread.
    //  Layout passed to visbasewidget by vis base containers. N
    //  Need to run a layout is initiated through 'runLayoutSlot'
    //  Process layout signal causes layout thread to begin laying elements out
    //  Once layout is finished running, the widget is updated in 'callUpdate()' function
    layoutThread = new LayoutThread;
    QThread* thread = new QThread;
    layoutThread->moveToThread(thread);
    connect(thread, SIGNAL(started()), layoutThread, SLOT(init())); //once thread launched, begin processing
    connect( this, SIGNAL( processLayoutSignal(VisBaseLayout*)), layoutThread, SLOT(processLayoutSlot(VisBaseLayout*)));
    connect(layoutThread, SIGNAL(layoutFinished()), this, SLOT(callUpdate()));//once layout finished, call update
    //  I am leaving out all signals and slots pertaining to finishing the layout
    //      the thread remains active over the lifetime of the widget
        //connect(layoutThread, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
        //connect(layoutThread, SIGNAL(finished()), thread, SLOT(quit()));//quit thread once layout is finished
        //connect(layoutThread, SIGNAL(finished()), layoutThread, SLOT(deleteLater())); //once finsished, delete layout
        //connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));//once finished, delete thread
    thread->start();

}

VisBaseWidget::~VisBaseWidget()
{
    //eventually add:
        //delete thread;
        //delete layoutThread;

}

void VisBaseWidget::loadData(QString pathToData)
{
    qDebug() << "VisBaseWidget load data " << pathToData << endl;//sanity check for proper inheritance

    //no default load data function
}

void VisBaseWidget::loadData( )
{
    qDebug() << "VisBaseWidget load data, no path to data " << endl;//sanity check for proper inheritance

    //no default load data function
}

void VisBaseWidget::advance()
{
    //empty for now
}

//this function is used to update the widget once a layout finishes running, or some other input is recieved
void VisBaseWidget::callUpdate()
{
    update();
}

//When user changes layout, process that signal.
void VisBaseWidget::runLayoutSlot(VisBaseLayout *layout)
{
    qDebug() << "got signal to run layout " << endl;
    emit(processLayoutSignal(layout));
}

//----------------SIZE AND SHAPE FUNCTIONS------------------

void VisBaseWidget::setGeometry(const QRectF &geom)
{
    prepareGeometryChange();
    QGraphicsWidget::setGeometry(geom);
    setPos(geom.topLeft());
}

void VisBaseWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)
{
    setGeometry(QRect(x, y, w, h));
}

QRectF VisBaseWidget::boundingRect() const
{
    return QRectF(QPointF(0,0), geometry().size());
}


QPainterPath VisBaseWidget::shape() const
{
    QPainterPath path;
    path.addRect(boundingRect());
    return path;
}

//------------------------ CONNECTION FUNCTIONS -----------------
void VisBaseWidget::lineConnect(VisBaseElement* e1, VisBaseElement* e2)
{
    LineConnectorElement* l = new LineConnectorElement( e1, e2, sageVisPointer, this, this);
    e1->forgeConnection(l, HOVER_CONNECTION );
    e2->forgeConnection(l, HOVER_CONNECTION );
    lineConnections << l;

}
